#!/usr/bin/env node
'use strict';

const {app, io, public_dir} = require('../server');
const debug = require('debug')(process.env.DEBUG || '');
const fs = require('fs');
const ifaces = require('os').networkInterfaces();

/*
  Because of proxying, it's safe to use http:// on
  the server. No need to load up keys here.
*/

const protocol = 'http';
const server = require(protocol).createServer(app);

/**
 *  Use the PORT environment variable or default to 3000.
 */

const port = process.env.PORT ?? '3000';
app.set('port', port);

/**
 *  Attach socket.io to the web server.
 */
io.attach(server);

/**
 *  Listen on provided port, on all network interfaces.
 */

server.listen(port);
server.on('error', handleError);
server.on('listening', handleListening);

/**
 *  Event listener for HTTP server "error" event.
 */

function handleError(error) {
  if (error.syscall !== 'listen') {
    throw error;
  }

  switch (error.code) {
  case 'EADDRINUSE':
    console.error(`Port ${port} is already being used`);
    process.exit(1);
    break;
  case 'EACCES':
    console.error(`Port ${port} requires elevated user privileges (sudo)`);
    process.exit(1);
    break;
  default:
    throw error;
  }
}

/**
 *  Callback for server listen event
 */

function handleListening() {
  const address = server.address();
  // Inspired by https://github.com/http-party/http-server/blob/master/bin/http-server#L163
  const interfaces = [];
  Object.keys(ifaces).forEach(function(dev) {
    ifaces[dev].forEach(function(details) {
      // Node v. 18+ returns a number (4, 6) for family;
      // earlier versions returned IPv4 or IPv6. This handles
      // both cases.
      if (details.family.toString().endsWith('4')) {
        interfaces.push(`-> ${protocol}://${details.address}:${address.port}/`);
      }
    });
  });
  debug(
    `  ** Serving from the ${public_dir}/ directory. **`
  );
}
